home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / answers / comp / Objective-C / sample < prev    next >
Text File  |  1994-04-17  |  24KB  |  964 lines

  1. Path: bloom-beacon.mit.edu!hookup!europa.eng.gtefsd.com!howland.reston.ans.net!EU.net!sun4nl!news.nic.surfnet.nl!tuegate.tue.nl!krait.es.ele.tue.nl!tiggr
  2. From: tiggr@es.ele.tue.nl (Tiggr)
  3. Newsgroups: comp.lang.objective-c,comp.answers,news.answers
  4. Subject: comp.lang.objective-c FAQ, part 3/3: A Sample Program
  5. Supersedes: <sample_764338065@es.ele.tue.nl>
  6. Followup-To: comp.lang.objective-c
  7. Date: 17 Apr 1994 16:04:32 GMT
  8. Organization: Eindhoven University of Technology
  9. Lines: 944
  10. Approved: news-answers-request@mit.edu
  11. Expires: 27 May 1994 16:04:28 GMT
  12. Message-ID: <sample_766598668@es.ele.tue.nl>
  13. Reply-To: tiggr@es.ele.tue.nl (Tiggr)
  14. NNTP-Posting-Host: krait.es.ele.tue.nl
  15. Summary: This third part of the comp.lang.objective-c FAQ postings
  16.         presents a simple sample program written in Objective-C.
  17. Originator: tiggr@krait.es.ele.tue.nl
  18. Xref: bloom-beacon.mit.edu comp.lang.objective-c:1452 comp.answers:4942 news.answers:18177
  19.  
  20. Archive-name: Objective-C/sample
  21. Version: $Id: sample.preamble,v 2.3 1994/01/28 13:27:07 tiggr Exp $
  22.  
  23.  
  24.         A simple sample
  25.         Objective-C program
  26.  
  27.  
  28. This is the third part in a series of three informational postings
  29. concerning comp.lang.objective-c.  This article presents a simple program
  30. written in Objective-C.  The program consist of several files which are
  31. contained in a shar file (see instructions below on how to unpack).  [Note,
  32. from version 2.3 of this file, the sample has been changed in order to
  33. reduce the number of compiler warnings (down to 1, which is in there for
  34. explanatory purposes) and to reflect the use of `+alloc' and `-init' instead
  35. of `+new'.]
  36.  
  37. The early version of this FAQ was compiled by Bill Shirley, with the aid of
  38. many people.  The current version is being maintained by Tiggr, aided by a
  39. lot of people, including Paul Sanchez and Bill Shirley.
  40.  
  41. Send your suggestions, additions, bug reports, comments and fixes to
  42. `tiggr@es.ele.tue.nl'.
  43.  
  44.  
  45. #---------------------------------- cut here ----------------------------------
  46. # This is a shell archive.  Remove anything before this line,
  47. # then unpack it by saving it in a file and typing "sh file".
  48. #
  49. # Wrapped by Pieter Schoenmakers <tiggr@viper> on Fri Apr 15 21:26:28 1994
  50. #
  51. # This archive contains:
  52. #    objc-sample    
  53. #
  54. # Existing files will not be overwritten.
  55. # Error checking via wc(1) will be performed.
  56.  
  57. LANG=""; export LANG
  58. PATH=/bin:/usr/bin:$PATH; export PATH
  59.  
  60. echo mkdir - objc-sample
  61. mkdir objc-sample
  62.  
  63. if test -f objc-sample/README
  64. then
  65.     echo Ok to overwrite existing file objc-sample/README\?
  66.     read answer
  67.     case "$answer" in
  68.     [yY]*)    echo Proceeding;;
  69.     *)    echo Aborting; exit 1;;
  70.     esac
  71.     rm -f objc-sample/README
  72.     if test -f objc-sample/README
  73.     then
  74.         echo Error: could not remove objc-sample/README, aborting
  75.         exit 1
  76.     fi
  77. fi
  78. echo x - objc-sample/README
  79. cat >objc-sample/README <<'@EOF'
  80. This directory contains the complete code for the "Simple Sample Objective-C
  81. program" described in the comp.lang.objective-c FAQ.  If you have a suitable
  82. compiler, use the supplied Makefile.  Otherwise, program output can be found
  83. in the file "output".
  84.  
  85. You should probably read "main.m" first.  It is very heavily annotated.
  86.  
  87. Also note and read the file COPYRIGHT.
  88. @EOF
  89. set `wc -lwc <objc-sample/README`
  90. if test $1$2$3 != 855366
  91. then
  92.     echo ERROR: wc results of objc-sample/README are $* should be 8 55 366
  93. fi
  94.  
  95. chmod 644 objc-sample/README
  96.  
  97. if test -f objc-sample/Char.h
  98. then
  99.     echo Ok to overwrite existing file objc-sample/Char.h\?
  100.     read answer
  101.     case "$answer" in
  102.     [yY]*)    echo Proceeding;;
  103.     *)    echo Aborting; exit 1;;
  104.     esac
  105.     rm -f objc-sample/Char.h
  106.     if test -f objc-sample/Char.h
  107.     then
  108.         echo Error: could not remove objc-sample/Char.h, aborting
  109.         exit 1
  110.     fi
  111. fi
  112. echo x - objc-sample/Char.h
  113. cat >objc-sample/Char.h <<'@EOF'
  114. #import <objc/Object.h>
  115.  
  116. @interface Char: Object
  117. {
  118.   int value;
  119. }
  120.  
  121. -init: (int) x;
  122. -report;
  123.  
  124. @end
  125. @EOF
  126. set `wc -lwc <objc-sample/Char.h`
  127. if test $1$2$3 != 111498
  128. then
  129.     echo ERROR: wc results of objc-sample/Char.h are $* should be 11 14 98
  130. fi
  131.  
  132. chmod 644 objc-sample/Char.h
  133.  
  134. if test -f objc-sample/Node.h
  135. then
  136.     echo Ok to overwrite existing file objc-sample/Node.h\?
  137.     read answer
  138.     case "$answer" in
  139.     [yY]*)    echo Proceeding;;
  140.     *)    echo Aborting; exit 1;;
  141.     esac
  142.     rm -f objc-sample/Node.h
  143.     if test -f objc-sample/Node.h
  144.     then
  145.         echo Error: could not remove objc-sample/Node.h, aborting
  146.         exit 1
  147.     fi
  148. fi
  149. echo x - objc-sample/Node.h
  150. cat >objc-sample/Node.h <<'@EOF'
  151. #import <objc/Object.h>
  152.  
  153. @interface Node : Object
  154. {
  155.   id next;
  156.   id data;
  157. }
  158.  
  159. -init: anItem;        // create a Node and store anItem in it
  160. -free;            // free a Node and return the item in it
  161. -next;            // report the id of the next node after this one
  162. -setNext: aNode;    // make the next node be aNode
  163.  
  164. @end
  165. @EOF
  166. set `wc -lwc <objc-sample/Node.h`
  167. if test $1$2$3 != 1456295
  168. then
  169.     echo ERROR: wc results of objc-sample/Node.h are $* should be 14 56 295
  170. fi
  171.  
  172. chmod 644 objc-sample/Node.h
  173.  
  174. if test -f objc-sample/Node.m
  175. then
  176.     echo Ok to overwrite existing file objc-sample/Node.m\?
  177.     read answer
  178.     case "$answer" in
  179.     [yY]*)    echo Proceeding;;
  180.     *)    echo Aborting; exit 1;;
  181.     esac
  182.     rm -f objc-sample/Node.m
  183.     if test -f objc-sample/Node.m
  184.     then
  185.         echo Error: could not remove objc-sample/Node.m, aborting
  186.         exit 1
  187.     fi
  188. fi
  189. echo x - objc-sample/Node.m
  190. cat >objc-sample/Node.m <<'@EOF'
  191. #import <objc/Object.h>
  192. #import "Node.h"
  193.  
  194. @implementation    Node: Object
  195.  
  196. -init: anItem
  197. {
  198.   self = [super init];
  199.   next = 0;
  200.   data = anItem;
  201.   return self;
  202. }
  203.  
  204. -free
  205. {
  206.   id tmp = data;
  207.   [super free];
  208.   return tmp;
  209. }
  210.  
  211. -next
  212. {
  213.   return next;
  214. }
  215.  
  216. -setNext: aNode
  217. {
  218.   next = aNode;
  219.   return self;
  220. }
  221.  
  222. @end
  223. @EOF
  224. set `wc -lwc <objc-sample/Node.m`
  225. if test $1$2$3 != 3249299
  226. then
  227.     echo ERROR: wc results of objc-sample/Node.m are $* should be 32 49 299
  228. fi
  229.  
  230. chmod 644 objc-sample/Node.m
  231.  
  232. if test -f objc-sample/Queue.h
  233. then
  234.     echo Ok to overwrite existing file objc-sample/Queue.h\?
  235.     read answer
  236.     case "$answer" in
  237.     [yY]*)    echo Proceeding;;
  238.     *)    echo Aborting; exit 1;;
  239.     esac
  240.     rm -f objc-sample/Queue.h
  241.     if test -f objc-sample/Queue.h
  242.     then
  243.         echo Error: could not remove objc-sample/Queue.h, aborting
  244.         exit 1
  245.     fi
  246. fi
  247. echo x - objc-sample/Queue.h
  248. cat >objc-sample/Queue.h <<'@EOF'
  249. #import <objc/Object.h>
  250. #import "Node.h"
  251.  
  252. @interface Queue: Object
  253. {
  254.   id head;
  255.   id tail;
  256.   unsigned qsize;
  257. }
  258.  
  259. -empty;            // clear out all contents of the Queue
  260. -put: anItem;        // put anItem on the Queue
  261. -get;            // return the item on top of the Queue
  262. -(unsigned int) size;    // tell us the current size of the Queue
  263.  
  264. @end
  265. @EOF
  266. set `wc -lwc <objc-sample/Queue.h`
  267. if test $1$2$3 != 1655319
  268. then
  269.     echo ERROR: wc results of objc-sample/Queue.h are $* should be 16 55 319
  270. fi
  271.  
  272. chmod 644 objc-sample/Queue.h
  273.  
  274. if test -f objc-sample/Queue.m
  275. then
  276.     echo Ok to overwrite existing file objc-sample/Queue.m\?
  277.     read answer
  278.     case "$answer" in
  279.     [yY]*)    echo Proceeding;;
  280.     *)    echo Aborting; exit 1;;
  281.     esac
  282.     rm -f objc-sample/Queue.m
  283.     if test -f objc-sample/Queue.m
  284.     then
  285.         echo Error: could not remove objc-sample/Queue.m, aborting
  286.         exit 1
  287.     fi
  288. fi
  289. echo x - objc-sample/Queue.m
  290. cat >objc-sample/Queue.m <<'@EOF'
  291. #import "Queue.h"
  292.  
  293. @implementation    Queue
  294.  
  295. -empty
  296. {
  297.   while([self size])
  298.     [[self get] free];
  299.   return self;
  300. }
  301.  
  302. -put: anItem
  303. {
  304.   if (tail)
  305.     tail = [[tail setNext : [[Node alloc] init: anItem]] next];
  306.   else
  307.     head = tail = [[Node alloc] init: anItem];
  308.   ++qsize;
  309.   return self;
  310. }
  311.  
  312. -get
  313. {
  314.   id contents;
  315.   id old_head = head;
  316.  
  317.   head = [head next];
  318.   contents = [old_head free];
  319.   if (--qsize == 0)
  320.     tail = head;
  321.   return contents;
  322. }
  323.  
  324. -(unsigned) size
  325. {
  326.   return qsize;
  327. }
  328.  
  329. @end
  330. @EOF
  331. set `wc -lwc <objc-sample/Queue.m`
  332. if test $1$2$3 != 3975486
  333. then
  334.     echo ERROR: wc results of objc-sample/Queue.m are $* should be 39 75 486
  335. fi
  336.  
  337. chmod 644 objc-sample/Queue.m
  338.  
  339. if test -f objc-sample/Stack.h
  340. then
  341.     echo Ok to overwrite existing file objc-sample/Stack.h\?
  342.     read answer
  343.     case "$answer" in
  344.     [yY]*)    echo Proceeding;;
  345.     *)    echo Aborting; exit 1;;
  346.     esac
  347.     rm -f objc-sample/Stack.h
  348.     if test -f objc-sample/Stack.h
  349.     then
  350.         echo Error: could not remove objc-sample/Stack.h, aborting
  351.         exit 1
  352.     fi
  353. fi
  354. echo x - objc-sample/Stack.h
  355. cat >objc-sample/Stack.h <<'@EOF'
  356. #import <objc/Object.h>
  357. #import "Node.h"
  358.  
  359. @interface Stack: Object
  360. {
  361.   id stack;
  362.   unsigned int stack_size;
  363. }
  364.  
  365. -empty;                // clear out all contents of the Stack
  366. -put: anItem;            // put anItem on the Stack
  367. -get;                // return the item on top of the Stack
  368. -(unsigned) size;        // tell us the current size of the Stack
  369.  
  370. @end
  371. @EOF
  372. set `wc -lwc <objc-sample/Stack.h`
  373. if test $1$2$3 != 1553318
  374. then
  375.     echo ERROR: wc results of objc-sample/Stack.h are $* should be 15 53 318
  376. fi
  377.  
  378. chmod 644 objc-sample/Stack.h
  379.  
  380. if test -f objc-sample/Stack.m
  381. then
  382.     echo Ok to overwrite existing file objc-sample/Stack.m\?
  383.     read answer
  384.     case "$answer" in
  385.     [yY]*)    echo Proceeding;;
  386.     *)    echo Aborting; exit 1;;
  387.     esac
  388.     rm -f objc-sample/Stack.m
  389.     if test -f objc-sample/Stack.m
  390.     then
  391.         echo Error: could not remove objc-sample/Stack.m, aborting
  392.         exit 1
  393.     fi
  394. fi
  395. echo x - objc-sample/Stack.m
  396. cat >objc-sample/Stack.m <<'@EOF'
  397. #import "Stack.h"
  398.  
  399. @implementation    Stack
  400.  
  401. -empty
  402. {
  403.   while([self size])
  404.     [[self get] free];
  405.   return self;
  406. }
  407.  
  408. -put: anItem
  409. {
  410.   stack = [[[Node alloc] init: anItem] setNext : stack];
  411.   ++stack_size;
  412.   return self;
  413. }
  414.  
  415. -get
  416. {
  417.   id contents;
  418.   id old_stack = stack;
  419.  
  420.   stack = [stack next];
  421.   contents = [old_stack free];
  422.   --stack_size;
  423.   return contents;
  424. }
  425.  
  426. -(unsigned) size
  427. {
  428.   return stack_size;
  429. }
  430.  
  431. @end
  432. @EOF
  433. set `wc -lwc <objc-sample/Stack.m`
  434. if test $1$2$3 != 3557407
  435. then
  436.     echo ERROR: wc results of objc-sample/Stack.m are $* should be 35 57 407
  437. fi
  438.  
  439. chmod 644 objc-sample/Stack.m
  440.  
  441. if test -f objc-sample/output
  442. then
  443.     echo Ok to overwrite existing file objc-sample/output\?
  444.     read answer
  445.     case "$answer" in
  446.     [yY]*)    echo Proceeding;;
  447.     *)    echo Aborting; exit 1;;
  448.     esac
  449.     rm -f objc-sample/output
  450.     if test -f objc-sample/output
  451.     then
  452.         echo Error: could not remove objc-sample/output, aborting
  453.         exit 1
  454.     fi
  455. fi
  456. echo x - objc-sample/output
  457. cat >objc-sample/output <<'@EOF'
  458. Output from demo, excluding Char class:
  459.  
  460. Include the Char class in the demo? (y/n): n
  461. queue:   5, stack:-5.0
  462. queue: 4.0, stack:  -4
  463. queue:   3, stack:-3.0
  464. queue: 2.0, stack:  -2
  465. queue:   1, stack:-1.0
  466. queue: 0.0, stack:   0
  467. queue:  -1, stack: 1.0
  468. queue:-2.0, stack:   2
  469. queue:  -3, stack: 3.0
  470. queue:-4.0, stack:   4
  471. queue:  -5, stack: 5.0
  472.  
  473. Output from demo, including Char class:
  474.  
  475. Include the Char class in the demo? (y/n): y
  476. queue:   5, stack:   h
  477. queue:   q, stack:-4.0
  478. queue:   3, stack:   j
  479. queue:   o, stack:-2.0
  480. queue:   1, stack:   l
  481. queue:   m, stack: 0.0
  482. queue:  -1, stack:   n
  483. queue:   k, stack: 2.0
  484. queue:  -3, stack:   p
  485. queue:   i, stack: 4.0
  486. queue:  -5, stack:   r
  487. @EOF
  488. set `wc -lwc <objc-sample/output`
  489. if test $1$2$3 != 29111679
  490. then
  491.     echo ERROR: wc results of objc-sample/output are $* should be 29 111 679
  492. fi
  493.  
  494. chmod 644 objc-sample/output
  495.  
  496. if test -f objc-sample/Char.m
  497. then
  498.     echo Ok to overwrite existing file objc-sample/Char.m\?
  499.     read answer
  500.     case "$answer" in
  501.     [yY]*)    echo Proceeding;;
  502.     *)    echo Aborting; exit 1;;
  503.     esac
  504.     rm -f objc-sample/Char.m
  505.     if test -f objc-sample/Char.m
  506.     then
  507.         echo Error: could not remove objc-sample/Char.m, aborting
  508.         exit 1
  509.     fi
  510. fi
  511. echo x - objc-sample/Char.m
  512. cat >objc-sample/Char.m <<'@EOF'
  513. #import <stdio.h>
  514. #import "Char.h"
  515.  
  516. @implementation Char
  517. {
  518.   int value;
  519. }
  520.  
  521. - init: (int) x
  522. {
  523.   [super init];        // In case the parent class is doing
  524.               // something special in its init...
  525.   value = x;
  526.   return self;
  527. }
  528.  
  529. - report
  530. {
  531.   printf("   %c", value);
  532.   return self;
  533. }
  534.  
  535. @end
  536. @EOF
  537. set `wc -lwc <objc-sample/Char.m`
  538. if test $1$2$3 != 2347279
  539. then
  540.     echo ERROR: wc results of objc-sample/Char.m are $* should be 23 47 279
  541. fi
  542.  
  543. chmod 644 objc-sample/Char.m
  544.  
  545. if test -f objc-sample/main.m
  546. then
  547.     echo Ok to overwrite existing file objc-sample/main.m\?
  548.     read answer
  549.     case "$answer" in
  550.     [yY]*)    echo Proceeding;;
  551.     *)    echo Aborting; exit 1;;
  552.     esac
  553.     rm -f objc-sample/main.m
  554.     if test -f objc-sample/main.m
  555.     then
  556.         echo Error: could not remove objc-sample/main.m, aborting
  557.         exit 1
  558.     fi
  559. fi
  560. echo x - objc-sample/main.m
  561. cat >objc-sample/main.m <<'@EOF'
  562. /* main.m - comp.lang.objective-c simple sample Objective-C program.  */
  563.  
  564. // This is a comment, just like the previous line.  Everything to the right
  565. // of a double slash is ignored.
  566.  
  567. /* Classes are the one real extension which Objective-C adds to C.  A class
  568.    is a description of a collection of data, like a C structure, and the
  569.    methods by which that data may be accessed or manipulated.  Instances of
  570.    a class are called objects, and methods are invoked by sending messages
  571.    to either the class itself, to produce objects, or to those objects.  The
  572.    recipient of a message is called a "receiver".  The form of a message is:
  573.  
  574.     [receiver method andMaybeSomeArguments]
  575.  
  576.    the receiver and method components are mandatory, as are the square
  577.    brackets surrounding the message.  Additional arguments may or may not be
  578.    present, depending upon the method definition.  Messages may appear
  579.    anywhere a statement is allowed in C.
  580.  
  581.    The first thing we do is bring in some include files, as in C.  On the
  582.    NeXT, it is customary to use the "import" statement which guarantees that
  583.    the file isn't included more than once.  Using GNU CC this is not all
  584.    that nice sinds it generates a huge warning for every file being
  585.    compiled.  So, since it does not really matter, we'll stick to
  586.    `#include'.  */
  587.  
  588. #import <stdio.h>
  589. #import <objc/Object.h>
  590. #import "Queue.h"
  591. #import "Stack.h"
  592.  
  593. /* That brought in class definitions for Objects, Queues, and Stacks.  The
  594.    Object class is the basis for all other classes, which is why it gets
  595.    brought in first.  It provides basic functional behavior which is
  596.    inherited by all derived classes.  All user created classes normally have
  597.    Object somewhere in their ancestry.
  598.  
  599.    Queue and Stack are classes of our own construction, and provide FIFO and
  600.    LIFO storage capabilities, respectively.  I'm not going to go into
  601.    implementation details here.  It's irrelevant how they work, all that is
  602.    important is that they both respond to 'put:' and 'get'.  If you want to
  603.    inspect them, look into the Queue.m, Stack.m, Queue.h and Stack.h files.
  604.  
  605.    A simple Class definition follows.  It inherits directly from the base
  606.    class "Object".  This gives it lots of nice properties, not the least of
  607.    which is the ability to be referenced by any pointer of the generic
  608.    object type "id".  All objects can be pointed to by any id variable, and
  609.    the default return type from methods is id.  This allows messages to be
  610.    embedded in other messages, either as receivers or arguments.
  611.  
  612.    An Int object allocates space for a single integer.  The "report" message
  613.    causes it to report its value.  Everything between the @implementation
  614.    and the @end is part of the class definition.
  615.  
  616.    Note - It is *highly* unusual to have a class implementation in your main
  617.    program.  Since the object is fully defined before it gets used, no
  618.    interface description is required.  There is nothing illegal about doing
  619.    things this way, but it is so unusual that the compiler will produce a
  620.    warning for this class.  The Int class implementation is here solely for
  621.    expository purposes.  */
  622.  
  623. @implementation Int: Object    // Int is derived from Object
  624. {
  625.     int value;        // This is the data portion.  Like a struct.
  626. }
  627.  
  628. /* The following are the method definitions.  A `+' prefix means it is a
  629.    factory method, i.e., how to manufacture instances of the class.  The
  630.    body of the method is between braces, like a C function.
  631.  
  632.    This class doesn't define any factory methods.  It relies on the +alloc
  633.    method defined in class Object.  For examples of factory methods, look at
  634.    the +new method defined in the Stack or Queue implementations.
  635.  
  636.    Self is a special variable, which refers to the object currently being
  637.    manipulated.  Super refers to the parent class of self.  The following
  638.    method asks the parent class (Object) to hand us a new instance, which
  639.    becomes self.  Then we update the instance variables and return a pointer
  640.    to the new object.
  641.  
  642.    It is standard for methods that do not need to return any special value
  643.    to instead return self.  This allows for a nested syntax of method calls.
  644.  
  645.    The "-" in front of init means that it's an instance method, i.e.,
  646.    something a particular object should respond to.  */
  647.  
  648. -init: (int) i
  649. {
  650.   /* We're overriding the `-init' of our superclass, but we add
  651.      functionality instead of replacing it.  Therefore, first call the
  652.      `-init' of our superclass.  */
  653.   [super init];
  654.   value = i;
  655.   return self;
  656. }
  657.  
  658. -report
  659. {
  660.   printf ("%4d", value);
  661.   return self;
  662. }
  663.  
  664. @end
  665.  
  666. /* We have implemented Float and Char classes more traditionally, using
  667.    separate files for the interface (.h) and implementation (.m).  The Float
  668.    and Char objects are like the Int object, but with the obvious difference
  669.    that they work with floats and characters.  We include the interface
  670.    definitions at this point.  */
  671.  
  672. #import "Float.h"
  673. #import "Char.h"
  674.  
  675. /* If you inspect those files, note polymorphism -- methods have same
  676.    names as in the Int class.  */
  677.  
  678. int main (void)
  679. {
  680.     /* First create instances of "Stack" and "Queue" data structures.  */
  681.     id queue = [[Queue alloc] init];
  682.     id stack = [[Stack alloc] init];
  683.     int i, reply;
  684.     
  685.     fprintf (stderr, "Include the Char class in the demo? (y/n): ");
  686.  
  687.     /* Anything not matching `y.*' means no.  */
  688.     reply = getchar ();
  689.  
  690.     for (i = 5; i > -6; --i)
  691.       {
  692.     /* Depending on which version of the demo we're running, we
  693.        alternately put Ints and Floats onto the queue and stack, or
  694.        Ints, Floats, and Chars.  */
  695.     if (reply == 'y')
  696.       {
  697.         /* If I is odd we put an Int on the queue and a Char on the
  698.            stack.  If I is even we put an Char on the queue and a Float
  699.            on the stack.
  700.  
  701.            Since there is more than one method `-init:' and since
  702.            `+alloc' returns a plain, typeless, `id', the compiler
  703.            doesn't know the type of the object returned by alloc.  An
  704.            explicit cast (i.e. static type indication) ensures that the
  705.            compiler knows which `init:' is invoked---the one accepting a
  706.            char or the other one accepting an int.
  707.  
  708.            Another solution, which avoids the static type indication, is
  709.            to put typing information on the method in the method's name.
  710.            This is done for the Float class.  */
  711.         id my_char = [(Char *) [Char alloc] init: 'm' + i];
  712.  
  713.         if (i & 1)
  714.           {
  715.         [queue put: [(Int *) [Int alloc] init: i]];
  716.         [stack put: my_char];
  717.           }
  718.         else
  719.           {
  720.         [queue put: my_char];
  721.         [stack put: [[Float alloc] initFloatValue: i]];
  722.           }
  723.           }
  724.     else
  725.       {
  726.         /* If I is odd we put an Int on the queue and a Float on the
  727.            stack.  If I is even we put a Float on the queue and an Int
  728.            on the stack.  */
  729.             [queue put: ((i & 1)
  730.              ? [(Int *) [Int alloc] init: i]
  731.              : [[Float alloc] initFloatValue: i])];
  732.             [stack put: ((i & 1)
  733.              ? [[Float alloc] initFloatValue: i]
  734.              : [(Int*) [Int alloc] init: i])];
  735.     }
  736.     }
  737.  
  738.     while ([queue size] && [stack size])
  739.       {
  740.     /* The following illustrates run-time binding.  Will report be
  741.        invoked for a Float object or an Int object?  Did the user elect
  742.        for Char objects at run time?  We don't know ahead of time, but
  743.        with run-time binding and polymorphism it works properly.  The
  744.        burden is on the class implementer rather than the class user.
  745.  
  746.        Note that the following lines remain unchanged, whether we are
  747.        using the Char class or not.  The queue and stack hand us the
  748.        next object, it reports itself regardless of its type, and then
  749.        it frees itself.  */
  750.  
  751.     printf ("queue:");
  752.     [[[queue get] report] free];
  753.     printf (", stack:");
  754.     [[[stack get] report] free];
  755.     putchar('\n');
  756.       }
  757.   return 0;
  758. }
  759. @EOF
  760. set `wc -lwc <objc-sample/main.m`
  761. if test $1$2$3 != 19712617780
  762. then
  763.     echo ERROR: wc results of objc-sample/main.m are $* should be 197 1261 7780
  764. fi
  765.  
  766. chmod 644 objc-sample/main.m
  767.  
  768. if test -f objc-sample/Makefile
  769. then
  770.     echo Ok to overwrite existing file objc-sample/Makefile\?
  771.     read answer
  772.     case "$answer" in
  773.     [yY]*)    echo Proceeding;;
  774.     *)    echo Aborting; exit 1;;
  775.     esac
  776.     rm -f objc-sample/Makefile
  777.     if test -f objc-sample/Makefile
  778.     then
  779.         echo Error: could not remove objc-sample/Makefile, aborting
  780.         exit 1
  781.     fi
  782. fi
  783. echo x - objc-sample/Makefile
  784. cat >objc-sample/Makefile <<'@EOF'
  785. # This Makefile assumes you have GNU gcc 2.3 or better and a suitable
  786. # runtime library with object support.  It also works on a NeXT.
  787. # Don't know about Stepstone.
  788.  
  789. .SUFFIXES: .o .m
  790. .m.o:
  791.     $(CC) -c $(CFLAGS) $<
  792.  
  793. # Use this on a NeXT
  794. #CC=        cc
  795. #LIBS=        
  796. # Use this with GNU CC on a non-NeXT,
  797. # and avoid the GCC moaning on using #import.
  798. CC=        gcc -Wno-import
  799. LIBS=        -lobjc
  800. LDFLAGS=    -L/usr/local/lib -L/usr/gnu/lib
  801.  
  802. CFLAGS=        -Wall -g
  803. OFILES=        main.o Node.o Queue.o Stack.o Float.o Char.o
  804.  
  805. demo: $(OFILES)
  806.     $(CC) $(CFLAGS) $(LDFLAGS) -o demo $(OFILES) $(LIBS)
  807.  
  808. clean:
  809.     rm -f $(OFILES) demo
  810.     
  811. Char.o : Char.m Char.h 
  812.  
  813. Float.o : Float.m Float.h 
  814.  
  815. Node.o : Node.m Node.h 
  816.  
  817. Queue.o : Queue.m Queue.h Node.h 
  818.  
  819. Stack.o : Stack.m Stack.h Node.h 
  820.  
  821. main.o : main.m Queue.h Node.h Stack.h Float.h
  822. @EOF
  823. set `wc -lwc <objc-sample/Makefile`
  824. if test $1$2$3 != 37127783
  825. then
  826.     echo ERROR: wc results of objc-sample/Makefile are $* should be 37 127 783
  827. fi
  828.  
  829. chmod 644 objc-sample/Makefile
  830.  
  831. if test -f objc-sample/Float.m
  832. then
  833.     echo Ok to overwrite existing file objc-sample/Float.m\?
  834.     read answer
  835.     case "$answer" in
  836.     [yY]*)    echo Proceeding;;
  837.     *)    echo Aborting; exit 1;;
  838.     esac
  839.     rm -f objc-sample/Float.m
  840.     if test -f objc-sample/Float.m
  841.     then
  842.         echo Error: could not remove objc-sample/Float.m, aborting
  843.         exit 1
  844.     fi
  845. fi
  846. echo x - objc-sample/Float.m
  847. cat >objc-sample/Float.m <<'@EOF'
  848. #import <stdio.h>
  849. #import "Float.h"
  850.  
  851. @implementation Float
  852. {
  853.   float value;
  854. }
  855.  
  856. -initFloatValue: (float) x
  857. {
  858.   [super init];
  859.   value = x;
  860.   return self;
  861. }
  862.  
  863. -report
  864. {
  865.   printf ("%4.1f", value);
  866.   return self;
  867. }
  868.  
  869. @end
  870. @EOF
  871. set `wc -lwc <objc-sample/Float.m`
  872. if test $1$2$3 != 2231215
  873. then
  874.     echo ERROR: wc results of objc-sample/Float.m are $* should be 22 31 215
  875. fi
  876.  
  877. chmod 644 objc-sample/Float.m
  878.  
  879. if test -f objc-sample/COPYRIGHT
  880. then
  881.     echo Ok to overwrite existing file objc-sample/COPYRIGHT\?
  882.     read answer
  883.     case "$answer" in
  884.     [yY]*)    echo Proceeding;;
  885.     *)    echo Aborting; exit 1;;
  886.     esac
  887.     rm -f objc-sample/COPYRIGHT
  888.     if test -f objc-sample/COPYRIGHT
  889.     then
  890.         echo Error: could not remove objc-sample/COPYRIGHT, aborting
  891.         exit 1
  892.     fi
  893. fi
  894. echo x - objc-sample/COPYRIGHT
  895. cat >objc-sample/COPYRIGHT <<'@EOF'
  896. This copyright notice applies to all source files distributed in the
  897. comp.lang.objective-c FAQ: `A Simple Sample Objective-C program'.
  898.  
  899. Copyright (C) 1993 Paul J. Sanchez and Bill Shirley
  900. Copyright (C) 1994 Pieter J. Schoenmakers
  901.  
  902. The `simple sample Objective-C program' is free software; you can
  903. redistribute it and/or modify it under the terms of the GNU General Public
  904. License as published by the Free Software Foundation; either version 2, or
  905. (at your option) any later version.
  906.  
  907. The `simple sample Objective-C program' is distributed in the hope that it
  908. will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  909. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  910. Public License for more details.
  911.  
  912. You should have received a copy of the GNU General Public License
  913. along with GNU Emacs; see the file COPYING.  If not, write to
  914. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  915. @EOF
  916. set `wc -lwc <objc-sample/COPYRIGHT`
  917. if test $1$2$3 != 19150944
  918. then
  919.     echo ERROR: wc results of objc-sample/COPYRIGHT are $* should be 19 150 944
  920. fi
  921.  
  922. chmod 644 objc-sample/COPYRIGHT
  923.  
  924. if test -f objc-sample/Float.h
  925. then
  926.     echo Ok to overwrite existing file objc-sample/Float.h\?
  927.     read answer
  928.     case "$answer" in
  929.     [yY]*)    echo Proceeding;;
  930.     *)    echo Aborting; exit 1;;
  931.     esac
  932.     rm -f objc-sample/Float.h
  933.     if test -f objc-sample/Float.h
  934.     then
  935.         echo Error: could not remove objc-sample/Float.h, aborting
  936.         exit 1
  937.     fi
  938. fi
  939. echo x - objc-sample/Float.h
  940. cat >objc-sample/Float.h <<'@EOF'
  941. #import <objc/Object.h>
  942.  
  943. @interface Float: Object
  944. {
  945.   float value;
  946. }
  947.  
  948. -initFloatValue: (float) x;
  949. -report;
  950.  
  951. @end
  952. @EOF
  953. set `wc -lwc <objc-sample/Float.h`
  954. if test $1$2$3 != 1114113
  955. then
  956.     echo ERROR: wc results of objc-sample/Float.h are $* should be 11 14 113
  957. fi
  958.  
  959. chmod 644 objc-sample/Float.h
  960.  
  961. chmod 755 objc-sample
  962.  
  963. exit 0
  964.